package org.zoomdy.gdbx.os;

import java.io.IOException;

import org.zoomdy.gdbx.Debugger;
import org.zoomdy.gdbx.OSNode;

public abstract class RTOS
{
    final static int THREAD_ID_ALL  = -1;
    final static int THREAD_ID_ANY  = 0;
    
    Debugger debugger;
    OSNode node;
    
    int debugLevel;
    boolean needUpdate;
    
    public RTOS(Debugger debugger, OSNode node)
    {
        this.debugger = debugger;
        this.node = node;
    }
    
    public abstract boolean detect();
    
    public void targetRunning()
    {
        this.needUpdate = true;
    }
    
    /*
     * ‘qfThreadInfo’
     * ‘qsThreadInfo’
     * Obtain a list of all active thread IDs from the target (OS). Since there may be
     * too many active threads to fit into one reply packet, this query works iteratively:
     * it may require more than one query/reply sequence to obtain the entire list of
     * threads. The first query of the sequence will be the ‘qfThreadInfo’ query;
     * subsequent queries in the sequence will be the ‘qsThreadInfo’ query.
     * NOTE: This packet replaces the ‘qL’ query (see below).
     * Reply:
     * ‘m thread-id ’
     *      A single thread ID
     * ‘m thread-id,thread-id ...’
     *      a comma-separated list of thread IDs
     * ‘l’
     *      (lower case letter ‘L’) denotes end of list.
     */
    public abstract String getThreadList(boolean first) throws IOException;
    
    /*
     * ‘qThreadExtraInfo,thread-id ’
     * Obtain a printable string description of a thread’s attributes from the target
     * OS. thread-id is a thread ID; see [thread-id syntax], page 504. This string may
     * contain anything that the target OS thinks is interesting for gdb to tell the
     * user about the thread. The string is displayed in gdb’s info threads display.
     * Some examples of possible thread extra info strings are ‘Runnable’, or ‘Blocked
     * on Mutex’.
     * Reply:
     * ‘XX ...’
     *      Where ‘XX ...’ is a hex encoding of ascii data, comprising the
     *      printable string containing the extra information about the thread’s
     *      attributes.
     * (Note that the qThreadExtraInfo packet’s name is separated from the com-
     * mand by a ‘,’, not a ‘:’, contrary to the naming conventions above. Please
     * don’t use this packet as a model for new packets.)
     */
    public abstract String getThreadInfo(int id) throws IOException;
    
    /*
     * ‘H op thread-id ’
     * Set thread for subsequent operations (‘m’, ‘M’, ‘g’, ‘G’, et.al.). op depends on the
     * operation to be performed: it should be ‘c’ for step and continue operations
     * (note that this is deprecated, supporting the ‘vCont’ command is a better op-
     * tion), ‘g’ for other operations. The thread designator thread-id has the format
     * and interpretation described in [thread-id syntax], page 504.
     * Reply:
     * ‘OK’ 
     *      for success
     * ‘E NN ’ 
     *      for an error
     */
    public abstract boolean setCurrentThread(String op, int id) throws IOException;
    
    /*
     * ‘qC’ Return the current thread ID.
     * Reply:
     * ‘QC thread-id ’
     *      Where thread-id is a thread ID as documented in [thread-id syntax],
     *      page 504.
     * ‘(anything else)’
     *      Any other reply implies the old thread ID.
     */
    public abstract int getCurrentThread() throws IOException;
    
    /*
     * ‘T thread-id ’
     * Find out if the thread thread-id is alive. See [thread-id syntax], page 504.
     * Reply:
     * ‘OK’ 
     *      thread is still alive
     * ‘E NN ’ 
     *      thread is dead
     */
    public abstract boolean isAliveThread(int id) throws IOException;
    
    /*
     * ‘g’
     * Read general registers.
     * Reply:
     * ‘XX...’
     *      Each byte of register data is described by two hex digits. The bytes
     *      with the register are transmitted in target byte order. The size of
     *      each register and their position within the ‘g’ packet are determined
     *      by the gdb internal gdbarch functions DEPRECATED_REGISTER_RAW_
     *      SIZE and gdbarch_register_name. The specification of several
     *      standard ‘g’ packets is specified below.
     *      When reading registers from a trace frame (see Section 13.2 [Using
     *      the Collected Data], page 161), the stub may also return a string
     *      of literal ‘x’’s in place of the register data digits, to indicate that
     *      the corresponding register has not been collected, thus its value is
     *      unavailable. For example, for an architecture with 4 registers of
     *      4 bytes each, the following reply indicates to gdb that registers 0
     *      and 2 have not been collected, while registers 1 and 3 have been
     *      collected, and both have zero value:
     *      -> g
     *      <- xxxxxxxx00000000xxxxxxxx00000000
     * ‘E NN ’
     *      for an error.
     */
    public abstract String readRegisters() throws IOException;

    public int getDebugLevel()
    {
        return debugLevel;
    }

    public void setDebugLevel(int debugLevel)
    {
        this.debugLevel = debugLevel;
    }
    
    void debug(int debugLevel, Object obj)
    {
        if(this.debugLevel >= debugLevel)
        {
            System.out.println("<" + debugLevel + ">" + this.getClass().getSimpleName() + ":" + obj);
        }
    }
}
